Repository navigation
feat(chat): sent images, line diffs, compaction marker, h4-h6 - #73
Merged
Merged
Conversation
One-tap messages (continue, yes, no, commit and push, retry to start with), as collie's Quick dock has. A reply goes through the composer's own send path, so it is queued while the agent works and taken as the answer when a question card is open; a draft in the box is left alone. The list lives in each device's settings: quick replies are a phone thing (a PC has a keyboard), so nothing is stored on the server. Settings -> Quick replies edits it (up to 12, 200 characters each; blank rows are kept while being typed and never shown), and a button beside the paperclip hides or shows the row, remembered per device. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The row takes a line above the message box on every pane; it now waits for the ⚡ button, and the choice is remembered per device as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Transcripts already record what each request filled:
- Codex: token_count events with last_token_usage and model_context_window
- Claude Code: assistant usage, input + cache creation + cache read,
subagent (sidechain) entries skipped
- omp/omo/gjc: message usage, input + cacheRead + cacheWrite
ConversationMetadata gains an optional `context { used, window }`. The
window is only what the transcript leaves no doubt about: Codex states it,
and a Claude request past 200k can only have run in the 1M window (kept
through a compaction). Otherwise the line shows the tokens used, never a
guessed percentage.
The composer shows `74% left` or `68k used`, red at 20% or less, with the
counts on hover. PaneTerminal's metadata dedupe compared only model and
effort, so it now compares the context too, or the number would never move.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, a loading state From comparing the chat with chatmux's: - A failed tool call looked like a success inside "Worked for…". Tool parts gain `error`: Claude's tool_result is_error and omp's toolResult isError, and for Codex, which records no flag, the output's own verdict (exit code, "Script failed", "apply_patch verification failed"; a completed script is judged as a whole). The row reads "failed" in red, its output is headed Error, and the block header counts failures. - A file path in a tool row opens the FileViewer, like paths in prose. - Codex's apply_patch, bare or as the string an exec script passes to tools.apply_patch, renders as a per-file diff and its row is summed up by the files it touches (shared/patch.ts, used by server and client). - The jump-to-latest button showed only for new messages; it now shows whenever the reader is scrolled up (a round arrow), and stays the "New messages" pill when there are some. - The chat said "No conversation yet" until the first answer came back; it now says it is loading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
More from comparing with chatmux's chat: - Images the user sent: Claude transcripts keep pasted images as base64 in the user entry. The parser now emits an image part naming it (`<entry uuid>:<block index>`, png/jpeg/gif/webp only) instead of the data, and GET /api/pane/conversation/image decodes it on request (immutable cache), so a 2 s poll never carries megabytes. Images this app attaches appear as `@…png` mentions and show through /api/fs/file. Thumbnails sit above the user bubble; a tap opens them. - Edit/MultiEdit render as one line diff (src/lib/diff.ts, an LCS that falls back to removed-then-added past 250k line pairs). - A compaction's summary, which was dropped, is a divider that opens to it. - Markdown headings #### to ###### render as h4-h6. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #72 (← #71 ← #70). Merge in order #70 → #71 → #72 → this.
More from comparing our chat with chatmux's (behavior only).
Images the user sent
{ kind: "image", media_type, ref: "<entry uuid>:<block index>" }with no data. Only png/jpeg/gif/webp are included; svg is excluded.GET /api/pane/conversation/image?pane_id&refresolves the pane's transcript and decodes that one block. It responds withcache-control: private, max-age=86400, immutableandnosniff./api/pane/, so it relays to remote PCs like the rest.@…/.herdr-web-ui/paste-….pngmentions and are shown through the existing/api/fs/file.Edit as a line diff
src/lib/diff.tsis an LCS line diff. Unchanged lines show once, and removed/added lines appear in place with-/+. Past 250k line pairs it falls back to removed-then-added. An empty side counts as no lines. MultiEdit'sedits[]each get their own diff.Compaction marker
Claude's
isCompactSummaryentry was dropped. It is now a divider, "Conversation compacted · time", which opens to the summary. One existing test asserted the drop and was updated deliberately.Markdown
####–######render as h4–h6. Below h3 the size stays the same; weight and then a dim colour tell the levels apart.Tests
bun run typecheck;bun test421/421;test:ui9/9.transcriptImagedecodes the named block and returns null for a text block, svg, another entry, a traversal-looking ref, or a missing file.lineDiff: placement, insertion/removal, and the size fallback.pane.report_agentdoes not setagent_sessionthere. The endpoint was checked to 404 a bad ref; the lookup itself is covered by thetranscriptImageunit test.####heading; no overflow.Not done
Codex
input_imageand omp image parts are not shown yet; this covers Claude and our own attachments.🤖 Generated with Claude Code